﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Microsoft.Xna.Framework.Input;

namespace Pavilion
{
    public class Link
    {
        public event EventHandler Disposed;
        public event Action<Link, ILock> LockAdded, LockRemoved;

        public IEnumerable<ILock> LockCollection { get { return lockCollection; } }
        public NodeBase StartingNode { get; private set; }
        public NodeBase EndingNode { get; private set; }
        public OpenCriteria OpenCriteria { get; set; }

        private List<ILock> lockCollection;

        internal Link(NodeBase startNode, NodeBase endNode)
        {
            this.StartingNode = startNode;
            this.EndingNode = endNode;
            this.lockCollection = new List<ILock>();
            this.OpenCriteria = OpenCriteria.Single;

            StartingNode.BindLink(this);
        }

        internal Link(NodeBase startNode, NodeBase endNode, IEnumerable<ILock> lockList, OpenCriteria openCriteria) : this(startNode, endNode)
        {
            if (lockList != null)
                this.lockCollection.AddRange(lockList);

            this.OpenCriteria = openCriteria;
        }

        public void Dispose()
        {
            lockCollection.Clear();
            lockCollection = null;
            StartingNode.UnbindLink(this);
            StartingNode = EndingNode = null;
            
            OnDisposed();
            Disposed = null;
        }

        public ILock GetLock(int index)
        {
            return lockCollection[index];
        }

        public void AddLock(ILock lockItem)
        {
            this.lockCollection.Add(lockItem);
            OnLockAdded(lockItem);
        }

        public void RemoveLock(ILock lockItem)
        {
            this.lockCollection.Remove(lockItem);
            OnLockRemoved(lockItem);
        }

        public void RemoveLockAt(int index)
        {
            RemoveLock(this.lockCollection[index]);
        }

        public int IndexOfLock(ILock lockItem)
        {
            return this.lockCollection.IndexOf(lockItem);
        }

        private void OnDisposed()
        {
            if (Disposed != null)
                Disposed(this, EventArgs.Empty);
        }

        private void OnLockAdded(ILock lockItem)
        {
            if (LockAdded != null)
                LockAdded(this, lockItem);
        }

        private void OnLockRemoved(ILock lockItem)
        {
            if (LockRemoved != null)
                LockRemoved(this, lockItem);
        }
    }

    public enum OpenCriteria
    {
        Single,
        All
    }
}
